#include "includes.h"

BOOL mcp_init()
{
	uint8_t value;
	char temp[10];
	mcp_reset(); 		// Send reset-kommando
	
	// Setup interrupts
	clear_bit(DDRE, DDE0);
//	set_bit(PORTE, PE0);
	set_bit(GICR, INT2);

	clear_bit(EMCUCR, ISC2); //falling edge

	// Self-test
	value = mcp_read_byte(MCP_CANSTAT);
	USART_print(itoa(value,temp,16));
	USART_print("\r\n");
	if ((value & MODE_MASK) != MODE_CONFIG) {
		USART_print("MCP2515 is NOT in configuration mode after reset!\r\n");
		return TRUE;
	}

	mcp_bit_modify(MCP_CANCTRL, MODE_NORMAL, MODE_MASK); // Set the CAN-controller to NORMAL mode

	mcp_bit_modify(CAN_INTE, ((1<<CAN_RX0IE)|(1<<CAN_RX1IE)), ((1<<CAN_RX0IE)|(1<<CAN_RX1IE)));
	value = mcp_read_byte(MCP_CANSTAT);
	if ((value & MODE_MASK) != MODE_NORMAL) {
		USART_print("MCP2515 is NOT in normal mode!\r\n");
		return TRUE;
	}

	return FALSE;
}


void mcp_reset()
{
	enable_spi_transmission(MCP);
	SPI_write(MCP_RESET);
	disable_spi_transmission(MCP);
	_delay_ms(100);
}


uint8_t mcp_read_byte(uint8_t address)
{
	uint8_t result;
	enable_spi_transmission(MCP); // Select CAN-controller
	SPI_write(MCP_READ); // Send read command
	SPI_write(address); // Send address
	SPI_write(address); // Send address
	result = SPI_read(); // Read result
	disable_spi_transmission(MCP); // Deselect CAN-controller
	_delay_us(10);
	return result;
}


void mcp_write_byte(uint8_t address, uint8_t data) 
{
	enable_spi_transmission(MCP); // Select CAN-controller
	SPI_write(MCP_WRITE); // Send write command
	SPI_write(address); // Send address
	SPI_write(data); // Send byte
	disable_spi_transmission(MCP); // Deselect CAN-controller
	_delay_us(10);
}


void mcp_rts(uint8_t buffer) //request to send at buffer
{
	uint8_t rts;
	rts = (buffer|MCP_RTS);
	enable_spi_transmission(MCP); // Select CAN-controller
	SPI_write(rts); // Send RTS command
	disable_spi_transmission(MCP); // Deselect CAN-controller
}


void mcp_bit_modify(uint8_t address, uint8_t data, uint8_t mask)
{
	enable_spi_transmission(MCP); // Select CAN-controller
	SPI_write(MCP_BIT_MODIFY); // Send bit modify command
	SPI_write(address);
	SPI_write(mask); // Can change all bits
	SPI_write(data);
	disable_spi_transmission(MCP); // Deselect CAN-controller
	_delay_us(100);
}


uint8_t mcp_read_status() 
{	
	uint8_t status;
	enable_spi_transmission(MCP); // Select CAN-controller
	_delay_ms(10);
	SPI_write(MCP_READ_STATUS);
	SPI_write(MCP_READ_STATUS);
	status = SPI_read();
	_delay_ms(10);
	disable_spi_transmission(MCP); // Deselect CAN-controller
	return status;
}

uint8_t mcp_rx_status(void)
{
	uint8_t status;
	enable_spi_transmission(MCP); // Select CAN-controller
	SPI_write(MCP_RX_STATUS);
	SPI_write(MCP_RX_STATUS);
	_delay_us(10);
	status = SPI_read();
	disable_spi_transmission(MCP); // Deselect CAN-controller
	return status;
}
